#pragma once
#include "non_copy_able.h"
#include "socket.h"
#include "functor.h"

namespace el
{
	class EventLoop;
	class Channel;
	class Connector : noncopyable
	{
	public:
		typedef Function<void(int)> ConnectErrorCallback;
		typedef Function<void(FD)> NewConnectCallback;

		enum ConnState { DISCONNECT, CONNECTING, CONNECTED };
		Connector(EventLoop* loop, SocketAddrIn& addr);
		~Connector();

		void setNewConnectionCallback(const NewConnectCallback& cb) { new_connect_cb_ = cb; }
		void setConnectErrorCallback(const ConnectErrorCallback& cb) { connect_error_cb_ = cb; }

		void start();
		void restart();
		void stop();

		void handleWrite();
		void handleError();

		void startInLoop();
		void stopInLoop();

		void setState(ConnState state) { state_ = state; }

	private:
		void connect();
		void connecting(FD fd);
		void retry(FD fd);
		FD removeChannel();
		void releaseChannel();

	private:
		unsigned long max_retry_ms_;
		unsigned long retry_ms_;
		static const unsigned long init_retry_ms_ = 500;

		EventLoop* loop_;
		Channel* channel_;
		SocketAddrIn addr_;
		Socket sock_;
		bool connect_;
		ConnState state_;

		NewConnectCallback new_connect_cb_;
		ConnectErrorCallback connect_error_cb_;
	};
}